﻿

(function (ns)
{
    //Members
    this.Constants = {
        MSG_NO_QUERIES_FOUND: "No results to display",
        MSG_GENERAL_FAILURE: "Something went wrong :( ",
        MSG_PROCESSING: "Working on it...",
        MSG_GENERAL_ASSIGN_SUCCESS: "View(s) assigned to you successfully :)",
        MSG_GENERAL_DELETE_WARNING: "The selected view(s) will be permanently deleted. Are you sure?",
        MSG_GENERAL_DELETE_SUCCESS: "View(s) deleted successfully :)",
        MSG_ERR_NO_CONTEXT: "No context found, operation aborted",
        ODATA_ENDPOINT_SUFFIX: "/api/data/v8.0/"
    };

    $(document).ready(function ()
    {
        try
        {
            //retrieve all System Users
            var systemUsers = retrieveSystemUsers();

            //bind data to system users list control
            bindEntityCollToSelectControl("SystemUsers", systemUsers, "fullname", "systemuserid");

            //handle select initial population 
            handleUserSelectionEvent();

            //handle system user selection event                         
            $("#SystemUsers").change(handleUserSelectionEvent);

            //handle operation execution event
            $("#executeAction").click(handleOperationExecution);
        }
        catch (error)
        {
            //nottify user with error message
            notifyError(error);
        }
    });

    //extract Global Context object 
    getContext = function ()
    {
        var result = null;

        if (typeof GetGlobalContext != "undefined")
        {
            result = GetGlobalContext();
        }
        else
        {
            if (typeof Xrm != "undefined")
            {
                result = Xrm.Page.context;
            }
            else
            {
                throw new Error(Constants.ERR_NO_CONTEXT);
            }
        }

        return result;
    }

    //retrieve all System Users
    retrieveSystemUsers = function ()
    {
        var result = null;

        //set OData end-point        
        var ODataEndpoint = getContext().getClientUrl() + Constants.ODATA_ENDPOINT_SUFFIX + "systemusers";

        //define query
        var query = "?$select=fullname&$orderby=fullname asc&$filter=islicensed eq true";

        //define request 
        var req = new XMLHttpRequest();
        req.open("GET", ODataEndpoint + query, false);
        req = setConstantRequestHeaders(req);
        req.onreadystatechange = function ()
        {
            if (this.readyState == 4 /* complete */)
            {
                req.onreadystatechange = null;
                if (this.status == 200)
                {
                    data = JSON.parse(this.response);
                    result = data.value;
                }
                else
                {
                    var error = JSON.parse(this.response).error;
                    notifyError(error.message);
                }
            }
        };
        req.send();

        return result;
    }

    //handle user selection event 
    handleUserSelectionEvent = function ()
    {
        //extract selected user id
        var userId = $("#SystemUsers").val();

        //retrieve all user queries owned by selected user
        var userQueries = retrieveUserOwnedPrivateQueries(userId);

        //bind data to system users list control            
        bindEntityCollToSelectControl("UserQueries", userQueries, "name", "userqueryid");
    }

    //bind data to select control
    bindEntityCollToSelectControl = function (controlId, data, labelDataItem, valueDataItem)
    {
        //empty current displayed options
        $("#" + controlId).empty();

        //handle empty data collection 
        if ((data == null) || (data.length == 0))
        {
            $("#" + controlId)
                .append($("<option></option>")
                .attr("value", -1)
                .text(Constants.MSG_NO_QUERIES_FOUND));

            $("#" + controlId).prop('disabled', true);
        }
        else
        {
            for (i = 0; i < data.length ; i++)
            {
                var optionText = data[i][labelDataItem];

                $("#" + controlId)
                    .append($("<option></option>")
                    .attr("value", data[i][valueDataItem])
                    .text(optionText));
            }

            $("#" + controlId).prop('disabled', false);
        }
    }

    //retrieve specified user owned private queries details
    retrieveUserOwnedPrivateQueries = function (userId)
    {
        var result = null;

        //set OData end-point        
        var ODataEndpoint = getContext().getClientUrl() + Constants.ODATA_ENDPOINT_SUFFIX + "userqueries";

        //define query
        var query = "?$select=name&$orderby=name asc&$filter=_ownerid_value eq " + userId

        //define request 
        var req = new XMLHttpRequest();
        req.open("GET", ODataEndpoint + query, false);
        req.setRequestHeader("MSCRMCallerID", userId);
        req = setConstantRequestHeaders(req);
        req.onreadystatechange = function ()
        {
            if (this.readyState == 4 /* complete */)
            {
                req.onreadystatechange = null;
                if (this.status == 200)
                {
                    data = JSON.parse(this.response);
                    result = data.value;
                }
                else
                {
                    var error = JSON.parse(this.response).error;
                    notifyError(error.message);
                }
            }
        };
        req.send();

        return result;
    }

    //handle operation execution
    handleOperationExecution = function ()
    {
        //extract view owner id 
        var viewOwnerId = $("#SystemUsers").val();

        //extract selected operation 
        var selectedOprtation = $('input[name=operation]:checked', '#manageUserQueryForm').val();

        //extract selected view id         
        var selectedViews = $('#UserQueries').val();

        if (selectedViews)
        {
            //execute according to selected operation 
            switch (selectedOprtation)
            {
                case "assign":
                    assignUserQueryRecords(selectedViews, viewOwnerId);
                    break;
                case "delete":
                    deleteUserQueryRecords(selectedViews, viewOwnerId);
                    break;
                    //this option is currently unsupported by Web API
                case "share":
                    break;
                default:
                    break;
            }
        }
        else
        {
            alert("Select target view(s)");
            $('#UserQueries').focus();
        }
    }

    //assign target records to current user 
    assignUserQueryRecords = function (targetRecords, viewOwnerId)
    {
        if (targetRecords.length > 0)
        {
            //notify user
            $("#userMessages").text(Constants.MSG_PROCESSING);

            //iterate through records collection
            for (var i = 0; i < targetRecords.length; i++)
            {
                //assign view
                assignRecordToCurrentUser("userqueries", targetRecords[i], viewOwnerId);
            }
        }
    }

    //assign target record to current user 
    assignRecordToCurrentUser = function (entityName, recordId, viewOwnerId)
    {
        //extract current user
        var currentUserId = getContext().getUserId().replace("{", "").replace("}", "");

        //set OData end-point        
        var ODataEndpoint = getContext().getClientUrl() +
            Constants.ODATA_ENDPOINT_SUFFIX + entityName +
            "(" + recordId + ")";

        //set owner as current user  
        var record = { "ownerid@odata.bind": "/systemusers(" + currentUserId + ")" };

        //define request 
        var req = new XMLHttpRequest();
        req.open("PATCH", ODataEndpoint, true);
        req.setRequestHeader("MSCRMCallerID", viewOwnerId);
        req = setConstantRequestHeaders(req);
        req.onreadystatechange = function ()
        {
            if (this.readyState == 4 /* complete */)
            {
                req.onreadystatechange = null;
                if (this.status == 204)
                {
                    //refresh views display
                    handleUserSelectionEvent();
                    //notify user
                    $("#userMessages").text(Constants.MSG_GENERAL_ASSIGN_SUCCESS);
                }
                else
                {
                    var error = JSON.parse(this.response).error;

                    //notify user
                    notifyError(error.message);
                }
            }
        };
        req.send(JSON.stringify(record));
    }

    //delete target records 
    deleteUserQueryRecords = function (targetRecords, viewOwnerId)
    {
        if (confirm(Constants.MSG_GENERAL_DELETE_WARNING))
        {
            if (targetRecords.length > 0)
            {
                //notify user
                $("#userMessages").text(Constants.MSG_PROCESSING);

                //iterate through records collection
                for (var i = 0; i < targetRecords.length; i++)
                {
                    //delete view
                    deleteRecord("userqueries", targetRecords[i], viewOwnerId);
                }
            }
        }
    }

    //delete target record  
    deleteRecord = function (entityName, recordId, viewOwnerId)
    {
        //set OData end-point        
        var ODataEndpoint = getContext().getClientUrl() +
            Constants.ODATA_ENDPOINT_SUFFIX + entityName +
            "(" + recordId + ")";

        //define request 
        var req = new XMLHttpRequest();
        req.open("DELETE", ODataEndpoint, true);
        req.setRequestHeader("MSCRMCallerID", viewOwnerId);
        req = setConstantRequestHeaders(req);
        req.onreadystatechange = function ()
        {
            if (this.readyState == 4 /* complete */)
            {
                req.onreadystatechange = null;
                if (this.status == 204)
                {
                    //refresh views display
                    handleUserSelectionEvent();

                    //notify user
                    $("#userMessages").text(Constants.MSG_GENERAL_DELETE_SUCCESS);
                }
                else
                {
                    var error = JSON.parse(this.response).error;

                    //notify user
                    $("#userMessages").text(Constants.MSG_GENERAL_FAILURE + error.message);
                }
            }
        };
        req.send();
    }

    //add constant XMLHTTPRequest headers to XMLHTTPRequest
    setConstantRequestHeaders = function(request)
    {
        var result = request;

        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.setRequestHeader("OData-MaxVersion", "4.0");
        request.setRequestHeader("OData-Version", "4.0");

        return result;
    }

    //notify user with error message 
    notifyError = function (error)
    {
        $("#userMessages").removeClass('userSuccessMessages').addClass('userFailureMessages');
        $("#userMessages").text(error.message);
    }

})(window.CreateLead = window.ManageUserQueries || {});
